package redis

import (
	"errors"
	"github.com/go-redis/redis"
	"math"
	"strconv"
	"time"
)

const (
	oneWeekInSeconds = 7 * 24 * 3600 // 投票过期时间
	scorePerVote     = 432           // 投票获得分值
)

// CreatePost 创建帖子
func CreatePost(postID, communityID int64) error {
	pipeline := rdb.TxPipeline() // 开启redis事务
	// 设置发帖时间
	pipeline.ZAdd(KeyPostTimeZSet, redis.Z{
		Score:  float64(time.Now().Unix()),
		Member: postID,
	})
	// 设置帖子分数
	pipeline.ZAdd(KeyPostScoreZSet, redis.Z{
		Score:  0,
		Member: postID,
	})
	// 添加帖子id到社区set
	cKey := KeyCommunitySetPF + strconv.Itoa(int(communityID))
	pipeline.SAdd(cKey, postID)
	_, err := pipeline.Exec() // 执行redis事务
	return err
}

// VoteForPost 投票
func VoteForPost(userID, postID string, value float64) error {
	// 1.判断投票是否过期
	postTime := rdb.ZScore(KeyPostTimeZSet, postID).Val()
	if float64(time.Now().Unix())-postTime > oneWeekInSeconds {
		return errors.New("投票时间已过")
	}
	// 2.查看当前用户给当前帖子的投票记录(赞成1,反对-1,不参与0)
	oValue := rdb.ZScore(KeyPostVotedZSetPF+postID, userID).Val()
	if oValue == value { // 判断这次投票的值与之前投票是否相同
		return errors.New("不允许重复投票")
	}
	var oPoint float64 // 分值变更方向(分值减少还是增加)
	if value > oValue {
		oPoint = 1
	} else {
		oPoint = -1
	}
	diff := math.Abs(oValue - value)
	_, err := rdb.ZIncrBy(KeyPostScoreZSet, oPoint*diff*scorePerVote, postID).Result()
	if err != nil {
		return err
	}
	// 3.记录用户为该帖子投票的数据
	if value == 0 {
		_, err = rdb.ZRem(KeyPostVotedZSetPF+postID, postID).Result()
	} else {
		_, err = rdb.ZAdd(KeyPostVotedZSetPF+postID, redis.Z{
			Score:  value,
			Member: userID,
		}).Result()
	}
	return err
}
